/*
var _b = [
   {_id : "2", description : "ASUS"}
   ,{_id : "3", description : "TOSHIBA"}
   ,{_id : "5", description : "ACER ASPIRE"}
   ,{_id : "5", description : "ACER DESKTOP"}
  ]
	,c   = {'_id' : 'asc', 'description' : 'asc'}

	,_s  = []
	,_m = _b
	,cnt = 0
	,crd = HPI.count(_b) - 1
	,_sk = [];



for(var k in c ){

	var t = c[k];
	
	_s  = HPI.sort(_b, 0, crd, k, t);
	
	if( cnt == 0 ){
		_m = HPI.mergeSorted(_s, _m);
		//console.log(_m);
	}
	else{

		_m = HPI.mergeSorted(HPI.keys(_m, _sk), _s);
		
	}
			   
	cnt++;
	
	_sk = _sk.concat([k]);

}
console.log(_m);
*/

if(   typeof openDatabase == 'function' ){
	var shortName = 'crcInv1';
	var version = '1.0';
	var displayName = 'CRC Database';
	var maxSize = 1024 * 1024 * 5; // in bytes
	var db = openDatabase(shortName, version, displayName, maxSize);

	function ExecuteReaderWithSingleCallback(query, db, callback, log){
	
		log = typeof log == 'undefined' ? true : false;
		callback = callback || function(t, r){}

		db.transaction(
			function (transaction) {
				//console.log('a');
				if( log ){
					console.log(' ---- ');
					console.log(query);
				}
				//console.log(this);
				transaction.executeSql(
					query
					,[]
					,function(transaction, result){
						//console.log(transaction);
						//console.log(result);
						//console.log(this);
						callback(transaction, result);
					}
					,function (transaction, error) {
						//console.log(transaction);
						if( log ){
							console.log(error);
						}
						//console.log(this);
						callback(transaction, error);
					}
				);
			}
		);

	}

	function printRows(r){
	
		if( r.rows == undefined ) {console.log("No result. " + r.message); return; }
		
		for(var i = 0, len = r.rows.length; i < len; i++){
			var row = r.rows.item(i)
			    ,_r   = "Row: " + ((i + 1).toString())
				,fI = 0;
			for (var field in row ){
				_r = _r + (fI == 0 ? "" : "," ) + " [" + field + "] : " + row[field];
				fI++;
			}
			console.log( _r );
		}
		
	}
	
	/*
	console.log(db);

	query = "DROP TABLE LoginSignature;";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	query = "DROP TABLE IF EXISTS LoginSignature;";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	query = "Create Table LoginSignature (_id integer not null primary key autoincrement, LoginID text, StoreID text,LoginTime text, Signature text)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	query = "INSERT INTO LoginSignature (_id, LoginID, StoreID,LoginTime, Signature) VALUES (null, 1, 1, '12:00:00', 'test')";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	query = "INSERT INTO LoginSignature (_id, LoginID, StoreID,LoginTime, Signature) VALUES (null, 1, 1, '12:00:00', 'test')";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	//note: error
	query = "INSERTs INTO LoginSignature (_id, LoginID, StoreID,LoginTime, Signature) VALUES (null, 1, 1, '12:00:00', 'test')";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	query = "Select _id, LoginID, StoreID, LoginTime, Signature From LoginSignature limit 1";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	query = "Select _id, LoginID, StoreID, LoginTime, Signature From LoginSignature;";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	//note: error
	query = "sSelect _id, LoginID, StoreID, LoginTime, Signature From LoginSignature limit 1";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	*/

	// query = "DROP TABLE a";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	
	// query = "DROP TABLE IF EXISTS a";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	
	// query = "CREATE TABLE a (field1 int, field2 varchar(5))";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	// //query = "INSERT INTO a VALUES(7, 'd')";
	// //ExecuteReaderWithSingleCallback(query, db, function(t, r){});	
	
	// query = "INSERT INTO a VALUES(4, '-a')";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});	
	
	// query = "INSERT INTO a VALUES(5, 'a')";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});	
	
	// query = "INSERT INTO a VALUES(6, 'b')";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});


	// query = "INSERT INTO a SELECT 1, 'a' UNION SELECT 2, 'b'";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});	
	
	// query = "INSERT INTO a (field2) VALUES ('c')";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});	
	
	// query = "INSERT INTO a (field2) VALUES ('d')";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	// query = "INSERT INTO a (field3) VALUES ('d')";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	// query = 'INSERT INTO a (field2) VALUES ("a\'a")';
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	// query = "INSERT INTO non_existing (field3) VALUES ('d')";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	// query = "SELECT * FROM A";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){	printRows(r);});
	
	// query = "UPDATE a SET field2 = 'e'";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	// query = "SELECT * FROM non_existing";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	

	//ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	//query = "DELETE FROM a";
	//ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	// query = "SELECT * FROM a LIMIT 2,1";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){
		// printRows(r);
	// });
	
	/*
	query = "SELECT * FROM (SELECT 'a' AS field1, 'b' AS field1)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	query = "SELECT [field1:1] FROM (SELECT 'a' AS field1, 'b' AS field1)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	query = "SELECT field1 FROM (SELECT 'a' AS field1)x, (SELECT 'a' AS field1)y";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	query = "SELECT field1 as 'a',field2 as 'a' FROM a";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	query = "SELECT 'a' as 'field', 'a' as 'field' FROM a";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	*/
	
	// var query = "DROP TABLE IF EXISTS b";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	// var query = "CREATE TABLE b(field1 int)";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	// var query = "INSERT INTO b VALUES(7)";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){});

	// var query = "SELECT * FROM(SELECT 3 as field1, field1 FROM(SELECT  4 as field1, a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	// var query = "SELECT 0 as field1, * FROM(SELECT 1 as field1, * FROM(SELECT 2 as field1, * FROM(SELECT 3 as field1, * FROM(SELECT  4 as field1, a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x)x)x";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	// var query = "SELECT * FROM(SELECT * FROM(SELECT * FROM(SELECT 3 as field1, * FROM(SELECT  4 as field1, a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x)x)x"
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	/*
	var query = "SELECT * FROM (SELECT 3 as field1, * FROM(SELECT  4 as field1, a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x"
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "SELECT 0 as field1, * FROM (SELECT a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x"
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = "SELECT * FROM(SELECT  4 as field1, a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x"
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "SELECT * FROM a,a"
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	*/
	
	// var query = "SELECT 0 as field1, * FROM ( SELECT 1 as field1, * FROM (SELECT 2 as field1 FROM ( SELECT 3 as field1, [field1:2], * FROM(SELECT  4 as field1, a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x)x)x";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	// var query = "SELECT 'a' as field1, * FROM b INNER JOIN a ON a.field1 < b.field1";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	// var query = "SELECT 'b' as field1, * FROM(SELECT *, 'a' as field1 FROM b INNER JOIN a ON a.field1 < b.field1)x";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	// var query = "SELECT a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	// var query = "SELECT * FROM(SELECT a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	// var query = "SELECT  'x' as field1, 'y' as field1, 'z' as field1, * FROM(SELECT a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	// var query = "SELECT * FROM(SELECT  'x' as field1, 'y' as field1,  'z' as field1, 'a' as field1, * FROM(SELECT a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	// var query = "SELECT 'a' as field1, * FROM(SELECT  'x' as field1, * FROM(SELECT a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	// var query = "SELECT * FROM(SELECT 'a' as field1, 'b' as field1, 'c' as 'field1', * FROM(SELECT  'x' as field1, 'y' as field1,  'z' as field1, * FROM(SELECT a.field1, b.field1, 10 as field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x)x";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	// var query = "SELECT * FROM(SELECT field1, 'x' as field1 FROM a)x INNER JOIN (SELECT field1, 'g' as field1 FROM b)y ON x.field1 < y.field1";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	/*
	var query = "SELECT * FROM (SELECT * FROM(SELECT field1, 'x' as field1, 'a' as field1 FROM a)x INNER JOIN (SELECT field1, 'g' as field1 FROM b)y ON x.field1 < y.field1)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = "SELECT * FROM(SELECT field1, 'x' as field1 FROM a)x INNER JOIN (SELECT field1, 'g' as field1 FROM b)y ON x.field1 < y.field1";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = "SELECT * FROM(SELECT * FROM a INNER JOIN b ON a.field1 < b.field1)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "SELECT 1 as ' where' FROM a";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = "SELECT * FROM (SELECT NULL AS 'field1' UNION ALL SELECT NULL as 'field1')x WHERE x.field1 IN (NULL)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = "SELECT * FROM (SELECT 1 AS 'field1', 0 as 'field2' UNION ALL SELECT 3 as 'field1', 0 as 'field2')x WHERE field1 IN (SELECT 'a' as fiel2, x.field1 + 1 FROM(SELECT 2 AS field1)x)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	*/
	
	/*
	var query = "SELECT 'z' as field1, * FROM(SELECT  'x' as field1, 'y' as field1,  'z' as field1, * FROM(SELECT a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "SELECT * FROM(SELECT 'z' as field1, * FROM(SELECT  'x' as field1, 'y' as field1,  'z' as field1, * FROM(SELECT a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1)x)x)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	*/
	
	{
	/*
	query = "SELECT b.field1, a.field1 FROM a, b ";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){		
		printRows(r);
	});
	
	query = "SELECT a.field1, b.field1 FROM a, b";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	query = "SELECT a.field1, b.field1 FROM a INNER JOIN b ON a.field1 < b.field1";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	query = "DROP TABLE IF EXISTS c";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	query = "CREATE TABLE c ([field .1] int)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});
	
	query = "INSERT INTO c VALUES(100)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){});	

	query = "SELECT * FROM c";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	

	query = "SELECT a.field1, a.field2 FROM a _a";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	query = "SELECT * FROM (SELECT * FROM (SELECT 'a' as 'field1')x)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	//causes ambiguous field "a.field1" (and it would have been the case if we use other types of JOINs)
	query = "SELECT * FROM a,a";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	

	//causes ambiguous field "a.field1" (and it would have been the case if we use other types of JOINs)
	query = "SELECT * FROM a, (SELECT 'value' as 'field1')a";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	//ambiguous field1
	query = "SELECT b.field1, a.field1 FROM a,b WHERE field1 = 6";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	

	//causes ambiguous field "a.field1" (and it would have been the case if we use other types of JOINs)
	query = "SELECT field1 FROM a, (SELECT 'value' as 'field1')a";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	//causes ambiguous field "a.field1" (and it would have been the case if we use other types of JOINs)
	query = "SELECT * FROM a, b A";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	//causes ambiguous field "a.field1" (and it would have been the case if we use other types of JOINs)
	query = "SELECT field1 FROM a, b";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	//does not cause duplicate correlation name
	query = "SELECT * FROM (SELECT * FROM(SELECT 'value' as 'field3')x)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	//does not cause ambiguous field (incorrect cartesian product):
	//only two fields of "a" (field1 and field2), and each row in "a" is duplicated twice.
	query = "SELECT * FROM a,a _a";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	//two rows: field1 and field2 are the values of "a" since it "a" was first specified; if "b" was first
	//specified, "field1" would have value 7.
	query = "SELECT * FROM a,b";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	//only 1 column, field1. field1 takes the value from b, since b.field1 was first specified in the list
	query = "SELECT b.field1, a.field1 FROM a,b";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	//only 1 column, field1. field1 takes the value from b, since b.field1 was first specified in the list
	query = "SELECT a.field1, b.field1 FROM a,b";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
		
	//only 1 column, field1. field1 takes the value from b, since b.field1 was first specified in the list
	query = "SELECT a.field1+1 as field1, a.field1 FROM a WHERE field1 = 6";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	query = "SELECT *,*, 'c' as 'c' FROM a";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	query = "SELECT * FROM (SELECT * FROM (SELECT 1 AS 'a', 2 AS 'b')tbl1 INNER JOIN (SELECT 1 AS 'a', 3 as 'c')tbl2 ON tbl1.a = tbl2.a)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	

	query = "SELECT * FROM (SELECT * FROM a INNER JOIN b ON a.field1 = b.field1)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	query = "SELECT * FROM b INNER JOIN a ON a.field1 < b.field1";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	query = "SELECT * FROM (SELECT * FROM a INNER JOIN b ON a.field1 < b.field1)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});		
	
	query = "SELECT  * FROM(SELECT * FROM (SELECT 1+1 AS 'field1', * FROM a INNER JOIN b ON a.field1 < b.field1)x)x";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	*/
	}
	
	/*
	var query = "SELECT  some_missing_field FROM a;";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	var query = "SELECT  min(field1) as 'test' FROM a WHERE field1 = 6 ORDER BY field1;";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	

	var query = "SELECT field2, SUM(field1) FROM a group by field2 HAVING SUM(field1+1) = 15;";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "SELECT 1 as field1, a.field1, b.field1 FROM b INNER JOIN a ON a.field1 < b.field1 GROUP BY a.field1, b.field1";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "SELECT (SELECT * FROM a) as 'a'";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = "DROP TABLE IF EXISTS c";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "CREATE TABLE c (field1 integer primary key autoincrement, field2 int not null)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "INSERT INTO c (field1, field2) VALUES (2, 'test1')";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = "INSERT INTO c (field1, field2) VALUES (40, 'test2')";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = "INSERT INTO c (field2) VALUES ('test2')";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	var query = "UPDATE c SET fields1 = 42 WHERE field1 = 40";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	var query = "INSERT INTO c (field2) VALUES ('test2')";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});		
	var query = "SELECT * FROM c";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = "DROP TABLE IF EXISTS tstTbl1";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "CREATE TABLE IF NOT EXISTS tstTbl1 (field1)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = 'insert into tstTbl1 values("""1""2")'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = 'insert into tstTbl1 values("1""2")'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});

	var query = 'insert into tstTbl1 values("1\\"2")'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	var query = 'SELECT field1 FROM tstTbl1'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r); console.log(r.rows.item(0).field1 === "1")});

	var query = 'SELECT * FROM (SELECT COUNT(*), COUNT(*), 1+1 FROM tstTbl1)x'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r); console.log(r.rows.item(0).field1 === "1")});

	var query = 'SELECT field1, field1 as "t" FROM tstTbl1'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r); console.log(r.rows.item(0).field1 === "1")});

	var query = 'insert into tstTbl1 values(null)'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	var query = 'select * from tstTbl1 where field1 is null'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = "CREATE TABLE IF NOT EXISTS tstTbl2 (field1 integer)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	
	var query = 'insert into tstTbl2 values("")'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});	
	
	var query = 'select * from tstTbl2'
	ExecuteReaderWithSingleCallback(query, db, function(t, r){printRows(r);});
	*/
	
	/*
	var query = "DROP TABLE IF EXISTS tbl3";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});
	query = "create table tbl3(a int, b int, c int)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});
	
	for(var i = 1, len = 1200; i <= len; i++){
		query = "Insert Into tbl3 values(?,?,?)".replace(/\?/g, i);
		ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){}, false);
	}
	
	// query = "select * from tbl3";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){printRows(r_or_e);
	// });
	
	var query = "DROP TABLE IF EXISTS tbl4";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});
	query = "create table tbl4 (d int, e int, f int)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});
	
	for(var i = 1, len = 900; i <= len; i++){
		query = "Insert Into tbl4 values(?,?,?)".replace(/\?/g, i);
		ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){}, false);					
	}
	
	// query = "select * from tbl4";
	// ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){printRows(r_or_e);
	// });
	
	query = "select tbl4.*, tbl3.a as _id from tbl3 inner join tbl4 on tbl3.a == tbl4.e where tbl3.a = 1 and tbl3.b = 1 order by tbl4.d";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){printRows(r_or_e);
	});
	*/
	
	var query = "DROP TABLE IF EXISTS tbl1";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});
	query = "create table tbl1(a int, b int, c int)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});	

	query = "insert into tbl1 values (1,1,1)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});	
	
	var query = "DROP TABLE IF EXISTS tbl2";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});
	query = "create table tbl2(a int, b int, c int)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});	

	query = "insert into tbl2 values (1,1,1)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){});	
	
	query = "select tbl1.*, tbl2.* from tbl1 inner join tbl2 on tbl1.a = tbl2.a order by cast(a as integer)";
	ExecuteReaderWithSingleCallback(query, db, function(t, r_or_e){printRows(r_or_e);
	});	
	
	
}



var key = null;
// Simply open the database once so that it is created with the required tables
$.indexedDB("MyECommerceSite", {
	"schema": {
		"1": function(versionTransaction){
			var catalog = versionTransaction.createObjectStore("catalog", {
				"keyPath": "itemId"
			});
			catalog.createIndex("price");
		},
		// This was added in the next version of the site
		"2": function(versionTransaction){
			var cart = versionTransaction.createObjectStore("cart", {
				"autoIncrement": true
			});
			cart.createIndex("itemId");
			var wishlist = versionTransaction.createObjectStore("wishlist", {
				"autoIncrement": false,
				"keyPath": "itemId"
			});
			wishlist.createIndex("name");
		}
	}
}).done(function(){
	// Once the DB is opened with the object stores set up, show data from all tables
	window.setTimeout(function(){
		loadFromDB("cart");
		loadFromDB("wishlist");
		downloadCatalog();
	}, 100)
});

function deleteDB(){
	// Delete the database 
	$.indexedDB("MyECommerceSite").deleteDatabase();
}

// Download a catalog from the server and save it to the DB
function downloadCatalog(){
	$.getJSON("catalog.json", function(data){
			$.indexedDB("MyECommerceSite").transaction("catalog").then(function(){
				console.log("Transaction completed, all data inserted");
				loadFromDB("catalog");
			}, function(err, e){
				console.log("Transaction NOT completed", err, e);
			}, function(transaction){
				var catalog = transaction.objectStore("catalog");
				catalog.clear();
				$.each(data, function(i){
					_(catalog.add(this));
				})
			});
	});
}

// Iterate over each record in a table and display it
function loadFromDB(table){
	emptyTable(table);
	_($.indexedDB("MyECommerceSite").objectStore(table).each(function(elem){
		addRowInHTMLTable(table, elem.key, elem.value);
	}));
}

// Sort a table based on an index that is setup
function sort(table, key){
	emptyTable(table);
	_($.indexedDB("MyECommerceSite").objectStore(table).index(key).each(function(elem){
		addRowInHTMLTable(table, elem.key, elem.value);
	}));
}

function emptyDB(table){
	_($.indexedDB("MyECommerceSite").objectStore(table).clear());
}

// Read an item from catalog and save it in cart
function addToCart(itemId){
	$.indexedDB("MyECommerceSite").objectStore("catalog").get(itemId).then(function(item){
		$.indexedDB("MyECommerceSite").objectStore("cart").add(item).done(function(){
			loadFromDB("cart");
		});
	}, function(err, e){
		alert("Could not add to cart");
	});
}

// Delete an item from cart
function removeFromCart(itemId){
	$.indexedDB("MyECommerceSite").objectStore("cart")["delete"](itemId).done(function(){
		loadFromDB("cart");
	});
}

// Using transactions, read object from cart, add it to wishlist if it does not exist 
// and then delete it from the cart. If any operation failes, all these will fail
function moveToWishlist(cartId){
	var transaction = $.indexedDB("MyECommerceSite").transaction(["cart", "wishlist"]);
	transaction.done(function(){
		loadFromDB("cart");
		loadFromDB("wishlist");
	});
	transaction.progress(function(transaction){
		transaction.objectStore("cart").get(cartId).done(function(item){
			transaction.objectStore("wishlist").add(item).fail(function(){
				alert("Already in the wishlist");
			}).done(function(){
				_(transaction.objectStore("cart")["delete"](cartId));
			});
			
		})
	});
}

// Read an item from catalog and add it to wishlist
function addToWishlist(itemId){
	$.indexedDB("MyECommerceSite").objectStore("catalog").get(itemId).then(function(item){
		$.indexedDB("MyECommerceSite").objectStore("wishlist").add(item).done(function(){
			loadFromDB("wishlist");
		})
	}, function(err, e){
		alert("Could not add to cart");
	});
}

function removeFromWishList(itemId){
	$.indexedDB("MyECommerceSite").objectStore("wishlist")["delete"](itemId).done(function(){
		loadFromDB("wishlist");
	});
}

 
function emptyTable(tableName){
	var table = document.getElementById(tableName);
	var header = table.getElementsByTagName("tr")[0];
	table.innerHTML = "";
	header && table.appendChild(header);
}

function addRowInHTMLTable(tableName, key, value){
	var actions = {
		"catalog": {
			"Add to cart": "addToCart",
			"Add to wishlist": "addToWishlist"
		},
		"cart": {
			"Move to Wishlist": "moveToWishlist",
			"Remove from Cart": "removeFromCart"
		},
		"wishlist": {
			"Remove from Wishlist": "removeFromWishList"
		}
	}
	table = document.getElementById(tableName);
	var row = document.createElement("tr");
	var html = ["<tr>"];
	html = html.concat(["<td class = 'key'>", key, "</td>"]);
	html = html.concat(["<td class = 'value'>", JSON.stringify(value).replace(/,/g, ",\n"), "</td>"]);
	html.push("<td class = 'action'>");
	for (var action in actions[tableName]) {
		html = html.concat("<a href = 'javascript:", actions[tableName][action], "(", key, ")'>", action, "</a>");
	}
	html.push("</td>");
	html.push("</tr>");
	row.innerHTML = html.join("");
	table.appendChild(row);
}

function _(promise){
	promise.then(function(a, e){
		console.log("Action completed", e.type, a, e);
	}, function(a, e){
		console.log("Action completed", e.type, a, e);
	}, function(a, e){
		console.log("Action completed", e.type, a, e);
	})
}
        
 //could not prepare statement (1 only a single result allowed for a SELECT that is part of an expression) 
/*
//------------------------------------------------
// This will improve our code to be more readable and shorter
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
// Now we can open our database
const dbName = "MyTestDatabase";

// This is what our customer data looks like.
const customerData = [
  { ssn: "444-44-4444", name: "Bill", age: 35, email: "bill@company.com" },
  { ssn: "555-55-5555", name: "Donna", age: 32, email: "donna@home.org" }
];

 
var request = indexedDB.open(dbName, 4);
 
request.onerror = function(event) {
  // Handle errors.
};
request.onupgradeneeded = function(event) {
  var db = event.target.result;
 
  // Create an objectStore to hold information about our customers. We're
  // going to use "ssn" as our key path because it's guaranteed to be
  // unique.
  var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });
 
  // Create an index to search customers by name. We may have duplicates
  // so we can't use a unique index.
  objectStore.createIndex("name", "name", { unique: false });
 
  // Create an index to search customers by email. We want to ensure that
  // no two customers have the same email, so use a unique index.
  objectStore.createIndex("email", "email", { unique: true });
 
  // Store values in the newly created objectStore.
  for (var i in customerData) {
    objectStore.add(customerData[i]);
  }
}
*/

/*
// Code to create object stores and add data
(function(){
  $.indexedDB("databaseName", {
    "schema": {
      "1": function(versionTransaction){
        versionTransaction.createObjectStore("objectStore1");
      },
      "2": function(versionTransaction){
        versionTransaction.createObjectStore("objectStore2");
      }
    }
  }).transaction(["objectStore1", "objectStore2"]).then(function(){
    console.log("Transaction completed");
  }, function(){
    console.log("Transaction aborted");
  }, function(t){
    console.log("Transaction in progress");
    t.objectStore("objectStore1").add({
      "valueProp": "val",
      "anotherProp": 2
    }, 1).then(function(){
      console.log("Data added");
    }, function(){
      console.log("Error adding data");
    });
  });
})();
*/


// var req = $.indexedDB("databaseName");
// req.onsuccess = function(event){
	// console.log(event);
// }

/*
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
function openIndexedDB(version) {
	const dbName = "MyTestDatabase";
	var request = version > 0 ? indexedDB.open(dbName, version) : indexedDB.open(dbName);
	request.onsuccess = function(e){
		console.log('onsuccess: ' + e.target.result.version.toString() + ' ' + version);
	}
	request.onupgradeneeded = function(e){
		console.log('onupgradeneeded: ' + e.target.result.version.toString() + ' ' + version);
	}
}

var version = 1
openIndexedDB(version+1);
openIndexedDB(version+2);
openIndexedDB(version+3);
openIndexedDB(version+4);
*/
/*
// This is what our customer data looks like.
const customerData = [
  { ssn: "444-44-4444", name: "Bill", age: 35, email: "bill@company.com" },
  { ssn: "555-55-5555", name: "Donna", age: 32, email: "donna@home.org" }
];

request.onerror = function(event) {
  // Handle errors.
};
request.onupgradeneeded = function(event) {
  var db = event.target.result;
 
  // Create an objectStore to hold information about our customers. We're
  // going to use "ssn" as our key path because it's guaranteed to be
  // unique.
  var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });
 
  // Create an index to search customers by name. We may have duplicates
  // so we can't use a unique index.
  objectStore.createIndex("name", "name", { unique: false });
 
  // Create an index to search customers by email. We want to ensure that
  // no two customers have the same email, so use a unique index.
  objectStore.createIndex("email", "email", { unique: true });
 
  // Store values in the newly created objectStore.
  for (var i in customerData) {
    objectStore.add(customerData[i]);
  }
}
*/

/*
//-----------------------------------

//local storage...
localStorage.setItem("a", JSON.stringify({
	"tables" : {
		"table1" : {
			rows : [{field1 : 1}]
		   ,fields : {field1 : {type : 'integer', isNullable : false}}
		}
	}
}));

console.log(localStorage.getItem("a"));
//console.log(localStorage);
*/



/*
console.log(HPI.isEqual(
	[{"LoginID" : 1, "StoreID" : 1, "LoginTime" : '23:59:59', "LoginSignature" : 'signature_test'}]
   ,[{"LoginID" : 1, "StoreID" : 1, "LoginTime" : '23:59:59', "LoginSignature" : 'signature_test'}]
));
*/

